package cn.zzf.algs.note.base.collection.v2;

import cn.zzf.algs.note.base.struct.Node;

import java.util.Iterator;
import java.util.function.Consumer;

/**
 * 使用单向链表实现的栈
 * @author GaoFeng2017
 * @date 2020/6/11 19:30
 */
public class LinkedStack<T> implements Iterable<T> {

    /** 首结点 */
    private Node<T> first;

    /** 当前队列大小 */
    private int size;

    public LinkedStack() {

    }

    /** 添加一个元素到链表头部 */
    public void push(T element) {

        if (first == null) {
            this.first = new Node<>(element, null);
        } else {
            // 核心思想： 类似于火车头，当新的火车头进行拼接时，之前的车厢全部接在新车头的后面
            // 过程描述： 创建一个新结点，该节点的子节点是之前的链表节点，这样新节点就是头
            this.first = new Node<>(element, this.first);
        }

        this.size++;

    }


    /** 删除链表头部的元素，并将删除的元素作为返回值返回 */
    public T pop() {
        if (first == null) {
            return null;
        } else {
            T element = first.getValue();
            first = first.getNext();
            this.size--;
            return element;
        }
    }


    /** 返回当前链表长度 */
    public int size() {
        return this.size;
    }


    @Override
    public Iterator<T> iterator() {
        return new Iterator<T>() {
            /** 当前节点 */
            private Node<T> currentNode = first;

            @Override
            public boolean hasNext() {
                return this.currentNode != null;
            }

            @Override
            public T next() {
                T element = this.currentNode.getValue();
                this.currentNode = currentNode.getNext();
                return element;
            }

        };
    }

    @Override
    public void forEach(Consumer<? super T> action) {
       for (T element : this) {
           action.accept(element);
       }
    }
}
